{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 作业三"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 写一个可以将MNIST图片向任意方向（上，下，左，右）移动一个像素功能。\n",
    "# 然后对训练集中的每张图片，创建四个位移后的副本，每个方向一个，添加到训练集。\n",
    "# 最后，在这个扩展过的训练集上训练模型，衡量其在测试集上的精度，来优化精度，这种人工扩展训练集的技术成为数据增广或训练集扩展"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\administrator.ieiwxx2xksvb332\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\feature_extraction\\text.py:17: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n",
      "  from collections import Mapping, defaultdict\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_mldata\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import precision_score, recall_score\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from scipy.ndimage.interpolation import shift\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "\n",
    "def show_img1(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)  # 重塑数组\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary)\n",
    "    plt.show()\n",
    "    \n",
    "def show_img2(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest') # nearest 最近邻插值 图片缩放\n",
    "    plt.axis('off')\n",
    "    plt.show()\n",
    "\n",
    "# 位移\n",
    "def shift_img(img, dy, dx):\n",
    "    img = img.reshape(28, 28)\n",
    "    shifted_image = shift(img, [dy, dx]) # shift（array,偏移量）\n",
    "    return shifted_image.reshape(-1)\n",
    "    \n",
    "def show_shifted_img(X,i,dy,dx):\n",
    "    some_digit = X[i]\n",
    "    some_digit_shifted = shift_img(some_digit, dy, dx).reshape(28,28)\n",
    "    plt.imshow(some_digit_shifted, cmap=matplotlib.cm.binary, interpolation='nearest')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 读取数据源，创建训练集好测试集\n",
    "%matplotlib inline\n",
    "mnist = fetch_mldata('MNIST original', data_home='./')\n",
    "X,y = mnist['data'], mnist['target']\n",
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[0:60000], y[60000:]\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]\n",
    "y_train_9 = (y_train==9)\n",
    "y_test_9 = (y_test==9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 7., 8., 8., 0., 7., 0., 2., 2., 5.])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAOcAAADnCAYAAADl9EEgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAEg0lEQVR4nO3dMUqcWxiAYediM5AmAUkQsgHRIk12YJHKLaRIVpFCENJkJbZuwsbGQNLYayBFSJMu8Ke7zR2PNzNjfDXPU/rx/xyQlw88jDObpmkD6Pnnrg8ALCZOiBInRIkTosQJUZs3zP0pF27fbNEPbU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUeKEKHFClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6LECVHihChxQtTmXR+AP+vLly/D+cuXL6+dvXnzZvjs4eHhUmdiMZsTosQJUeKEKHFClDghSpwQJU6Ics/5lzk7OxvOr66urp19/vx53cdhwOaEKHFClDghSpwQJU6IEidEuUr5y7x//37pZ3d3d9d4Em5ic0KUOCFKnBAlTogSJ0SJE6LECVHuOR+Yy8vL4fymj4zNZrNrZ9vb20udieXYnBAlTogSJ0SJE6LECVHihChxQpR7zgfm5OTk1t59cHBwa+/mv2xOiBInRIkTosQJUeKEKHFClDghyj3nA/Pt27fhfJqm4fzFixfXzh49erTUmViOzQlR4oQocUKUOCFKnBAlTogSJ0S557xnzs/Ph/MPHz4M56P/S7uxsbHx6tWra2fz+Xz4LOtlc0KUOCFKnBAlTogSJ0SJE6Jcpdwz379/H85//Pix0vv39/dXep71sTkhSpwQJU6IEidEiROixAlR4oQo95x/mefPnw/nOzs7f+gk3MTmhChxQpQ4IUqcECVOiBInRIkTotxz3jPHx8crPf/27dvhfGtra6X3sz42J0SJE6LECVHihChxQpQ4IUqcEDWbpmk0Hw5Zv69fvw7nz549W+n9Hz9+HM739vZWej9LWfi9jDYnRIkTosQJUeKEKHFClDghSpwQ5fOcMScnJ8P5bLbwSux/c495f9icECVOiBInRIkTosQJUeKEKFcpMVdXVys9P5/P13QS7prNCVHihChxQpQ4IUqcECVOiBInRLnnfGDevXt310dgTWxOiBInRIkTosQJUeKEKHFClDghyj1nzKdPn1Z6/uDgYE0n4a7ZnBAlTogSJ0SJE6LECVHihChxQtRsmqbRfDhk/Z4+fTqcP378eDg/PT0dzp88efLbZ+LWLfxeR5sTosQJUeKEKHFClDghSpwQ5SNjMbPZwr+q/2t7e3s4d1XycNicECVOiBInRIkTosQJUeKEKHFClHvOmPl8Ppz//Plzpfnmpl/5fWFzQpQ4IUqcECVOiBInRIkTosQJUS69Yl6/fj2cHx0dDecXFxfD+c7Ozu8eiTtic0KUOCFKnBAlTogSJ0SJE6LECVHihChxQpQ4IUqcECVOiBInRIkTosQJUbNpmkbz4RBYi4VfympzQpQ4IUqcECVOiBInRIkTosQJUeKEKHFClDghSpwQJU6IEidEiROixAlR4oQocUKUOCFKnBAlTogSJ0SJE6I2b5gv/Jd9wO2zOSFKnBAlTogSJ0SJE6LECVG/AOulX7ZtnnydAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_img2(X_train,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_digit = X_train[0:1]\n",
    "test_digit.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr = np.array([0,0,0,0,0,\n",
    "                     0,0,1,0,0,\n",
    "                     0,1,0,1,0,\n",
    "                     0,0,1,0,0,\n",
    "                     0,0,0,0,0]).reshape(5,5)\n",
    "test_arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_down = shift(test_arr, [1,0]) # 下移一行\n",
    "test_arr_down"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_up = shift(test_arr, [-1,0]) # 上移一行\n",
    "test_arr_up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 1],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_right = shift(test_arr, [0,1]) # 右移一行\n",
    "test_arr_right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_left = shift(test_arr, [0,-1]) # 左移一行\n",
    "test_arr_left"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 使用一个简单的图形矩阵演示shift方法时如何操作的，观察矩阵和图像的变化关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,3)) # 绘制图形\n",
    "plt.subplot(1,5,1) # 第一张子图\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_arr, cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,2) # 第二张\n",
    "plt.title('move 1pixel to right', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [0,1]), cmap=matplotlib.cm.binary) # 右移\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('move 1pixel to below', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [1,0]), cmap=matplotlib.cm.binary) # 下移\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('move 1pixel to left', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [0,-1]), cmap=matplotlib.cm.binary) # 左移\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('move 1pixel to above', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [-1,0]), cmap=matplotlib.cm.binary) # 上移\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img = X_train[0]\n",
    "test_img.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(784,)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img_right = shift_img(X_train[0], 0, 1)\n",
    "test_img_right.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(test_img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(test_img_right)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  25,\n",
       "       227, 127,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,  78, 252, 170,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0, 201, 252, 126,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  27, 253, 252, 100,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0, 106, 253, 252,  21,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 124, 255, 204,   9,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,  48, 242, 253, 132,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  64, 252,\n",
       "       253,  63,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "        64, 252, 225,  21,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0, 152, 252, 124,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  22, 253, 253,  45,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0, 101, 252, 252,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0, 127, 252, 244,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252, 121,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 171, 252,\n",
       "        42,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "       233, 216,  18,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0, 232, 189,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 223, 194,   4,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0, 127, 252,  42,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 127, 252,  42,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "        25, 227, 127,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,  78, 252, 170,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 201, 252, 126,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  27, 253, 252, 100,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0, 106, 253, 252,  21,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0, 124, 255, 204,   9,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  48, 242, 253,\n",
       "       132,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  64,\n",
       "       252, 253,  63,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,  64, 252, 225,  21,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0, 152, 252, 124,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,  22, 253, 253,  45,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0, 101, 252, 252,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 127, 252, 244,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252, 121,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 171,\n",
       "       252,  42,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0, 233, 216,  18,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0, 232, 189,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0, 223, 194,   4,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0, 127, 252,  42,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252,  42,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img_right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 查看mnist数据集效果\n",
    "plt.figure(figsize=(15,3))\n",
    "plt.subplot(1,5,1)\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_digit.reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,2)\n",
    "plt.title('move 5pixel to right', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('move 5pixel to below', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('move 5pixel to left', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,-5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('move 5pixel to above', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,-5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 a\n",
      "2 b\n",
      "3 c\n",
      "4 d\n",
      "5 e\n"
     ]
    }
   ],
   "source": [
    "x=[1,2,3,4,5]\n",
    "y=['a','b','c','d','e']\n",
    "\n",
    "# zip 并行遍历\n",
    "for i,j in zip(x,y):\n",
    "    print(i,j)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Wall time: 39.7 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "X_train_shifted = []\n",
    "y_train_shifted = []\n",
    "\n",
    "for img, label in zip(X_train, y_train):\n",
    "    for dx, dy in [[1,0],[0,1], [-1,0],[0,-1]]:\n",
    "        X_train_shifted.append(shift_img(img, dx, dy))\n",
    "        y_train_shifted.append(label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000, 784)"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted = np.array(X_train_shifted)\n",
    "X_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000,)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted = np.array(y_train_shifted)\n",
    "y_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,  25, 227, 127,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,  78, 252, 170,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0, 201, 252, 126,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,  27, 253, 252, 100,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 106, 253, 252,  21,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 124, 255, 204,\n",
       "         9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  48, 242,\n",
       "       253, 132,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "        64, 252, 253,  63,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,  64, 252, 225,  21,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 152, 252, 124,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,  22, 253, 253,  45,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0, 101, 252, 252,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252, 244,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252,\n",
       "       121,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "       171, 252,  42,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0, 233, 216,  18,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0, 232, 189,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0, 223, 194,   4,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0, 127, 252,  42,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 127, 252,  42,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,\n",
       "         0,   0,   0,   0], dtype=uint8)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 1., 1., 7., 7., 7., 7., 8., 8.])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000,)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted_9 = (y_train_shifted==9)\n",
    "y_train_shifted_9.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "knn_clf = KNeighborsClassifier() # K近邻算法 KNeighborsClassifier\n",
    "knn_clf.fit(X_train_shifted, y_train_shifted_9)\n",
    "# 速度太慢。。。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_shifted[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_img1 = X_train_shifted[0:1]\n",
    "test_img1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn_clf.predict(test_img1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "train_score = cross_val_score(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, scoring='accuracy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_score.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "y_train_pred = cross_val_predict(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, verbose=3, n_jobs=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_train_shifted_9, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('精度：{0:.2f} %'.format(100*precision_score(y_train_shifted_9, y_train_pred)))\n",
    "print('召回率：{0:.2f} %'.format(100*recall_score(y_train_shifted_9, y_train_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "y_test_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('精度：{0:.2f} %'.format(100*precision_score(y_test_9, y_test_pred)))\n",
    "print('召回率：{0:.2f} %'.format(100*recall_score(y_test_9, y_test_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "accuracy_score(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 运行速度慢，结果没有正常显示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
